﻿using System.ComponentModel;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Linq;
using System.Waf.Applications;
using System.Waf.Applications.Services;
using HighLandirect.Applications.Properties;
using HighLandirect.Applications.Services;
using HighLandirect.Applications.ViewModels;
using HighLandirect.Applications.Views;
using HighLandirect.Domain;
using HighLandirect.Domain.Reports;
using HighLandirect.Foundation;
using System.Collections.Generic;
using System;
using System.Printing;

namespace HighLandirect.Applications.Controllers
{
    [Export]
    public class OrderController : Controller
    {
        private readonly IQuestionService questionService;
        private readonly CompositionContainer container;
        private readonly IEntityService entityService;
        private readonly ShellViewModel shellViewModel;
        private readonly DelegateCommand addNewCommand;
        private readonly DelegateCommand removeCommand;
        private readonly DelegateCommand printCommand;
        private readonly DelegateCommand showOrderHistoryBySendCustomerCommand;
        private readonly DelegateCommand addOrderFromSelectedHistoryCommand;
        //private readonly DelegateCommand filterOrderHistoryCommand;
        private OrderListViewModel orderListViewModel;
        private OrderViewModel orderViewModel;
        

        [ImportingConstructor]
        public OrderController(CompositionContainer container, IEntityService entityService, ShellViewModel shellViewModel,
                    OrderViewModel orderviewModel, IQuestionService questionService)
        {
            this.container = container;
            this.entityService = entityService;
            this.shellViewModel = shellViewModel;
            this.addNewCommand = new DelegateCommand(AddNewOrder, CanAddOrder);
            this.removeCommand = new DelegateCommand(RemoveOrder, CanRemoveOrder);
            this.printCommand = new DelegateCommand(PrintOrder, CanPrintOrder);
            this.printCommand = new DelegateCommand(PrintOrder, CanPrintOrder);
            //this.filterOrderHistoryCommand = new DelegateCommand(FilterOrderHistory, CanFilterOrderHistory);
            this.showOrderHistoryBySendCustomerCommand = new DelegateCommand(ShowOrderHistoryBySendCustomer, CanShowOrderHistoryBySendCustomer);
            this.addOrderFromSelectedHistoryCommand = new DelegateCommand(AddOrderFromSelectedHistory, CanAddOrderFromSelectedHistory);
            this.orderViewModel = orderviewModel;
            this.questionService = questionService;
        }


        public void Initialize()
        {            
            IOrderListView orderListView = container.GetExportedValue<IOrderListView>();
            orderListViewModel = new OrderListViewModel(orderListView, entityService.Orders,
                                                                entityService.Stores,
                                                                entityService.ReportMemos);
            orderListViewModel.AddNewCommand = addNewCommand;
            orderListViewModel.RemoveCommand = removeCommand;
            orderListViewModel.PrintCommand = printCommand;
            //orderListViewModel.FilterOrderHistoryCommand = filterOrderHistoryCommand;
            orderListViewModel.PropertyChanged += OrderListViewModelPropertyChanged;
            orderListViewModel.ShowOrderHistoryBySendCustomerCommand = showOrderHistoryBySendCustomerCommand;
            orderListViewModel.AddOrderFromSelectedHistoryCommand = addOrderFromSelectedHistoryCommand;
            shellViewModel.OrderListView = orderListViewModel.View;

            orderListViewModel.SelectedOrder = orderListViewModel.Orders.FirstOrDefault();
        }

        private int resceiveCustNo;
        private int sendCustNo;
        public int ResceiveCustNo
        {
            get { return this.resceiveCustNo; }
            set
            {
                this.resceiveCustNo = value;
                if (this.SendCustNo > 0)
                    this.AddNewOrder();
            }
        }
        public int SendCustNo
        {
            get { return this.sendCustNo; }
            set
            {
                this.sendCustNo = value;
                this.orderListViewModel.SendCustomerId = this.sendCustNo.ToString();
                this.ShowOrderHistoryBySendCustomer();
                if (this.ResceiveCustNo > 0)
                {
                    this.AddNewOrder();
                }
            }
        }

        private bool CanAddOrder() { return orderViewModel.IsValid; }
        private void AddNewOrder()
        {
            //テンポラリにOrderテーブル使っちゃったら同時実行はできんな。。。

            //最大番号プラス1
            long OrderID;
            if (orderListViewModel.Orders == null 
                || orderListViewModel.Orders.Count() == 0)
            {
                //一件目のときは履歴の最大番号
                if (orderListViewModel.OrderHistories == null 
                    ||orderListViewModel.OrderHistories.Count() == 0)
                {
                    OrderID = 1;
                }
                else
                {
                    OrderID = entityService.OrderHistories
                                        .OrderByDescending(x => x.OrderID)
                                        .FirstOrDefault().OrderID + 1;
                }
            }
            else
            {
                //二件目以降は画面のデータを使う
                OrderID = entityService.Orders
                                    .OrderByDescending(x => x.OrderID)
                                    .FirstOrDefault().OrderID + 1;
            }
            Order order = Order.CreateOrder(OrderID, System.DateTime.Now, this.ResceiveCustNo, this.SendCustNo, 2);

            entityService.Orders.Add(order);

            this.resceiveCustNo = 0;
            this.sendCustNo = 0;

            orderListViewModel.SelectedOrder = order;
            orderViewModel.Focus();
        }

        private bool CanRemoveOrder() { return orderListViewModel.SelectedOrder != null; }
        private void RemoveOrder()
        {
            foreach (Order order in orderListViewModel.SelectedOrders.ToArray())
            {
                entityService.Orders.Remove(order);
            }
        }

        private bool CanShowOrderHistoryBySendCustomer() { return true; }
        private void ShowOrderHistoryBySendCustomer()
        {
            //新しい注文履歴50件を表示する
            this.orderListViewModel.OrderHistories =
                    entityService.OrderHistories.Where(x => x.CustomerMasterSend.CustNo.ToString() ==  this.orderListViewModel.SendCustomerId)
                                                .OrderByDescending(x => x.OrderDate)
                                                .Take(50);
        }

        private bool CanAddOrderFromSelectedHistory() { return true; }
        private void AddOrderFromSelectedHistory()
        {
            int intCustomerId;
            if(!int.TryParse(orderListViewModel.SendCustomerId, out intCustomerId))
            {
                return;
            }

            foreach (var ResceiveCustomer in orderListViewModel.SelectedOrderHistories)
            {
                this.resceiveCustNo = ResceiveCustomer.ReceiveCustID;
                this.sendCustNo = intCustomerId;
                this.AddNewOrder();
            }
        }

        //private bool CanFilterOrderHistory(object CustomerIdText) { return true; }
        //private void FilterOrderHistory(object CostomerIdText)
        //{
        //    this.orderListViewModel.OrderHistories =
        //            entityService.OrderHistories.Where(x => x.CustomerMasterSend.CustNo.ToString() == CostomerIdText.ToString());
        //}

        private bool CanPrintOrder() { return orderListViewModel.Orders != null && (orderListViewModel.Orders.Count() > 0); }
        private void PrintOrder()
        {
            if (this.questionService.ShowYesNoQuestion("印刷しますか？"))
            {
                PrintOrderCore();
            }
        }

        private void PrintOrderCore()
        {

            try
            {
                LocalPrintServer ps = new LocalPrintServer();
                PrintQueue pq;
                try
                {
                    pq = ps.GetPrintQueue("FUJITSU FMPR5000"); //指定したプリンタ
                    pq.UserPrintTicket.PageMediaSize = new PageMediaSize(10 * 96, 4.5 * 96); //pixcel指定。1pixel=1/96inchだそうで
                    pq.UserPrintTicket.PageResolution = new PageResolution(96, 96);
                    pq.UserPrintTicket.InputBin = InputBin.Tractor;
                }
                catch (PrintQueueException)
                {
                    try
                    {   //PrimoPDF
                        pq = ps.GetPrintQueue("PrimoPDF");
                    }
                    catch (PrintQueueException)
                    {
                        pq = ps.DefaultPrintQueue; //どれもダメなら既定のプリンタ
                    }
                }

                var printer = new PrintCutSheetReport<OrderSource, ReportYamato>(pq);

                var orderSources = new List<OrderSource>();
                foreach (var order in this.orderListViewModel.Orders)
                {
                    var orderSource = new OrderSource(order);

                    orderSource.CustomerCD = this.orderListViewModel.SelectedStore.CustomerCD;
                    orderSource.StoreId1 = this.orderListViewModel.SelectedStore.StoreId1;
                    orderSource.StoreId2 = this.orderListViewModel.SelectedStore.StoreId2;
                    orderSource.ReportMemo = this.orderListViewModel.SelectedReportMemo.ReportMemo1;

                    orderSources.Add(orderSource);
                }

                printer.Print(orderSources);

                //OrderからOrderHistoryへレコードをmove
                foreach (var order in entityService.Orders)
                {
                    this.entityService.OrderHistories.Add(OrderHistory.CreateOrderHistory(order.OrderID,
                                                                                     order.OrderDate,
                                                                                     order.ReceiveCustID,
                                                                                     order.SendCustID,
                                                                                     order.ProductID));
                }

                //最終発送を更新
                this.entityService.Customers.Where(x => x.CustNo.ToString() == this.orderListViewModel.SendCustomerId)
                                            .First().LatestSend = DateTime.Now;
                //最終宛先を更新
                foreach (var order in this.entityService.Orders)
                {
                    this.entityService.Customers.Where(x => x.CustNo == order.CustomerMasterReceive.CustNo)
                                            .First().LatestResceive = DateTime.Now;
                }
                this.entityService.Orders.Clear();
            }
            catch
            {
                throw;
            }
        }

        private void UpdateCommands()
        {
            addNewCommand.RaiseCanExecuteChanged();
            removeCommand.RaiseCanExecuteChanged();
        }

        private void OrderListViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "SelectedOrder")
            {
                orderViewModel.Order = orderListViewModel.SelectedOrder;
                UpdateCommands();
            }
        }

        private void OrderViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "IsValid")
            {
                UpdateCommands();
            }
        }
    }
}
